<template>
  <div class="container" ref="container">
    <PropertySetting ref="propertySettingRef" :node="nodeClick" v-model="processForm" :lf="lf" :disabled="disabled"
      :skipConditionShow="skipConditionShow" :nodes="nodes" :skips="skips">
      <template v-slot:[key]="data" v-for="(item, key) in $slots">
        <slot :name="key" v-bind="data || {}"></slot>
      </template>
    </PropertySetting>
  </div>
</template>

<script setup name="Design">
import LogicFlow from "@logicflow/core";
import "@logicflow/core/dist/style/index.css";
import {Control, DndPanel, Menu, SelectionSelect} from '@logicflow/extension';
import '@logicflow/extension/lib/style/index.css'
import { ElLoading } from 'element-plus'
import Start from "@/components/WarmFlow/js/start";
import Between from "@/components/WarmFlow/js/between";
import Serial from "@/components/WarmFlow/js/serial";
import Parallel from "@/components/WarmFlow/js/parallel";
import End from "@/components/WarmFlow/js/end";
import Skip from "@/components/WarmFlow/js/skip";
import PropertySetting from '@/components/WarmFlow/PropertySetting/index.vue'
import { queryDef, saveJson } from "&/api/flow/definition";
import {
  json2LogicFlowJson,
  logicFlowJsonToWarmFlow
} from "@/components/WarmFlow/js/tool";
import useAppStore from "@/store/app";
const appStore = useAppStore();
const appParams = computed(() => useAppStore().appParams);

const { proxy } = getCurrentInstance();

const lf = ref(null);
const definitionId = ref(null);
const nodeClick = ref(null);
const disabled = ref(false);
const processForm = ref({});
const propertySettingRef = ref({});
const value = ref({});
const jsonString = ref('');
const skipConditionShow = ref(true);
const nodes = ref([]);
const skips = ref([]);

onMounted(async () => {
  if (!appParams.value) await appStore.fetchTokenName();
  definitionId.value = appParams.value.id;
  if (appParams.value.disabled === 'true') {
    disabled.value = true
  }
  use();
  lf.value = new LogicFlow({
    container: proxy.$refs.container,
    grid: true,
    keyboard: {
      enabled: true,
    },
  });
  register();
  initDndPanel();
  initControl();
  initMenu();
  initEvent();
  if (definitionId.value) {
    queryDef(definitionId.value).then(res => {
      jsonString.value = res.data;
      if (jsonString.value) {
        value.value = json2LogicFlowJson(jsonString.value);
        lf.value.render(value.value);
      }
    }).catch(() => {
      lf.value.render({});
    });
  }
  if (!definitionId.value) {
    proxy.$modal.notifyError("流程id不能为空！");
    lf.value.render({});
  }
})

/**
 * 初始化拖拽面板
 */
function initDndPanel() {
  lf.value.extension.dndPanel.setPatternItems([
    {
      type: 'start',
      text: '开始',
      label: '开始节点',
      icon: '',
    },
    {
      type: 'between',
      text: '中间节点-或签',
      label: '中间节点-或签',
      icon: '',
      className: 'important-node',
      properties: {collaborativeWay: '1'},
    },
    {
      type: 'between',
      text: '中间节点-票签',
      label: '中间节点-票签',
      icon: '',
      className: 'important-node',
      properties: {collaborativeWay: '2', nodeRatio: '50'},
    },
    {
      type: 'between',
      text: '中间节点-会签',
      label: '中间节点-会签',
      icon: '',
      className: 'important-node',
      properties: {collaborativeWay: '3'},
    },
    {
      type: 'serial',
      text: '',
      label: '互斥网关',
      properties: {},
      icon: '',
    },
    {
      type: 'parallel',
      text: '',
      label: '并行网关',
      properties: {},
      icon: '',
    },
    {
      type: 'end',
      text: '结束',
      label: '结束节点',
      icon: '',
    },
  ]);
}
/**
 * 初始化控制面板
 */
function initControl() {
  if (!disabled.value) {
    // 控制面板-清空画布
    lf.value.extension.control.addItem({
      iconClass: 'lf-control-clear',
      title: 'clear',
      text: '清空',
      onClick: (lf, ev) => {
        lf.clearData()
      }
    })
    // 控制面板-清空画布
    lf.value.extension.control.addItem({
      iconClass: 'lf-control-save',
      title: '',
      text: '保存',
      onClick: (lf, ev) => {
        const loadingInstance = ElLoading.service(({ fullscreen: true , text: "保存中，请稍等"}))
        let graphData = lf.getGraphData()
        value.value['nodes'] = graphData['nodes']
        value.value['edges'] = graphData['edges']
        value.value['id'] = definitionId.value
        let jsonString = logicFlowJsonToWarmFlow(value.value);
        saveJson(jsonString).then(response => {

          if (response.code === 200) {
            proxy.$modal.msgSuccess("保存成功");
            close();
          }
        }).finally(() => {
          nextTick(() => {
            loadingInstance.close();
          });
        });
      }
    });
  }
}
/**
 * 初始化菜单
 */
function initMenu() {
  // 为菜单追加选项（必须在 lf.render() 之前设置）
  lf.value.extension.menu.addMenuConfig({
    nodeMenu: [
      {
        text: "属性",
        callback(node) {
          alert(`
          节点id：${node.id}
          节点类型：${node.type}
          节点坐标：(x: ${node.x}, y: ${node.y})
          文本坐标：(x: ${node.text.x}, y: ${node.text.y})`);
        },
      },
    ],
    edgeMenu: [
      {
        text: "属性",
        callback(edge) {
          alert(`
          边id：${edge.id}
          边类型：${edge.type}
          边坐标：(x: ${edge.x}, y: ${edge.y})
          文本坐标：(x: ${edge.text.x}, y: ${edge.text.y})
          源节点id：${edge.sourceNodeId}
          目标节点id：${edge.targetNodeId}`);
        },
      },
    ],
  });
}
/**
 * 注册自定义节点和边
 */
function register() {
  lf.value.register(Start);
  lf.value.register(Between);
  lf.value.register(Serial);
  lf.value.register(Parallel);
  lf.value.register(End);
  lf.value.register(Skip);
}

/**
 * 添加扩展
 */
function use() {
  LogicFlow.use(DndPanel);
  LogicFlow.use(SelectionSelect);
  LogicFlow.use(Control);
  LogicFlow.use(Menu);
}
function initEvent() {
  const { eventCenter } = lf.value.graphModel
  eventCenter.on('node:dbclick', (args) => {
    nodeClick.value = args.data
    let graphData = lf.value.getGraphData()
    nodes.value = graphData['nodes']
    skips.value = graphData['edges']
    proxy.$nextTick(() => {
      propertySettingRef.value.show()
    })
  })

  eventCenter.on('edge:dbclick  ', (args) => {
    nodeClick.value = args.data
    const nodeModel = lf.value.getNodeModelById(nodeClick.value.sourceNodeId);
    skipConditionShow.value = nodeModel['type'] === 'serial'
    let graphData = lf.value.getGraphData()
    nodes.value = graphData['nodes']
    skips.value = graphData['edges']
    proxy.$nextTick(() => {
      propertySettingRef.value.show(nodeModel['nodeType'] === 'serial')
    })
  })

  eventCenter.on('edge:add', (args) => {
    lf.value.changeEdgeType(args.data.id, 'skip')
    // 修改边类型
    lf.value.setProperties(args.data.id, {
      skipType: 'PASS'
    })
  })

  eventCenter.on('blank:click', () => {
    nodeClick.value = null
    proxy.$nextTick(() => {
      propertySettingRef.value.handleClose()
    })
  })
}
/** 关闭按钮 */
function close() {
  window.parent.postMessage({ method: "close" }, "*");
}
</script>

<style scoped>
.container {
  width: 100%;
  height: 800px;
}
</style>
<style>
.lf-control-see {
  background-image: url('');
}

.lf-control-save {
  background-image: url('');
}
.lf-control-clear {
  background-image:url('');
}
</style>
